//
// Created by denglibin on 19-10-25.
//
/**
 *多线程并发服务器
 **/

//
// Created by denglibin on 19-10-25.
//
/*多进程并发服务器*/

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <string.h>
#include <ctype.h>
#include <wait.h>
#include <errno.h>
#include <pthread.h>
#include "wrap.h"

static const int port = 8888;

/**
 * 工作线程函数
 * @param client_socket_fd
 */
void* work_fun(void * arg){
    pthread_detach(pthread_self());// 分离线程 不用pthread_join 回收
    int client_socket_fd = (int)arg;
    char buf[1024];
    while(1){
        bzero(buf, 1024);
        int len = recv(client_socket_fd, buf, sizeof(buf), 0); // 接收数据
        printf("%s", buf);
        if(len <= 0){
            printf("client disconnected\n");
            Close(client_socket_fd);
            break;
        }
        for(int i = 0; i < len; i++){
            buf[i] = toupper(buf[i]);
        }
        Send(client_socket_fd, buf, len, 0); //发送数据
    }
    return NULL;
}

/**
 * 启动服务
 */
static void start_server(){
    int status = 1;
    int socket_fd = Socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in addr;

    struct sockaddr_in client_addr;
    int  sock_size = sizeof(struct sockaddr_in);
    char buf[1024];
    memset(buf, 0, 1024);
    bzero(&addr, sizeof(addr));

    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = htonl(INADDR_ANY);
    addr.sin_port = htons(port);
    Bind(socket_fd, (struct sockaddr*) &addr, sizeof(struct sockaddr));
    Listen(socket_fd, 128);
    printf("wait for connection...\n");

    while (status){
        int client_socket_fd = Accept(socket_fd, (struct sockaddr *) &client_addr, &sock_size);
        inet_ntop(AF_INET, &client_addr.sin_addr.s_addr, buf, sizeof(buf));
        printf("client ip = %s, port = %d\n", buf, ntohs(client_addr.sin_port));
        pthread_t  work_thread;
        pthread_create(&work_thread, NULL, work_fun, (void *) client_socket_fd);
    }

}

static int main_(int argc, char * argv[]){
    start_server();
    return 0;
}